﻿using UnityEngine;
using System.Collections.Generic;
using LitJson;

/// <summary>
/// 游戏控制器，处理玩家的消息
/// </summary>
public class GameManager : MonoBehaviour {

    public List<Transform> bornPoints;

    //存储所有玩家的字典
    protected Dictionary<string, Player> players = new Dictionary<string, Player>();


    //保存本地玩家引用
    Player localPlayer;

    void Awake()
    {
        EventManager.AllPlayerEnterGame += AllEnterGame;
        EventManager.playerMove += PlayerMove;
        EventManager.playerPosition += PlayerPos;
        EventManager.PlayerLogout += OnLogOut;
        EventManager.PlayerFire += OnPlayerFire;
        EventManager.PlayerOnHit += OnPlyaerHit;
        EventManager.PlayerOnDead += OnPlayerDead;
    }

    private void OnDestroy()
    {
        EventManager.AllPlayerEnterGame -= AllEnterGame;
        EventManager.playerMove -= PlayerMove;
        EventManager.playerPosition -= PlayerPos;
        EventManager.PlayerLogout -= OnLogOut;
        EventManager.PlayerFire -= OnPlayerFire;
        EventManager.PlayerOnHit -= OnPlyaerHit;
        EventManager.PlayerOnDead -= OnPlayerDead;
    }

    //所有玩家进入游戏
    void AllEnterGame(List<UserData> list)
    {
        foreach (var user in list)
        {
            Player player = CreatePlayer(user);
            if (user.username == UIManager.Instance.localUserData.username)
            {
                //给主角的Player添加控制器
                player.gameObject.AddComponent<LocalController>();
            }
        }
    }

    //玩家死亡
    void OnPlayerDead(UserData user)
    {
        players[user.username].OnDead();
    }
    /// <summary>
    /// //登录成功回调
    /// </summary>
    /// <param name="json">登录信息</param>
    /// <param name="islocal">是否本地玩家</param>
    //void OnLogin(string json, bool islocal)
    //{
    //    UserData user = JsonUtility.FromJson<UserData>(json);
    //    Player player = CreatePlayer(user);
    //    //是自己的玩家
    //    if (islocal)
    //    {
    //        GameObject.FindObjectOfType<LocalController>().SetLocol(player);
    //        localPlayer = player;
    //    }
    //    else
    //    {
    //        //发送自己的位置给服务器
    //        localPlayer.userData.pos = localPlayer.transform.position;
    //        string jsonstr = JsonUtility.ToJson(localPlayer.userData);
    //        //user.pos = localPlayer.transform.position;//新玩家的位置，不是自己的位置
    //        NetworkManager.Instance.SendMessage(Protocol.PlayerPosition_CMD, jsonstr);
    //    }
    //}

    void OnLogOut(UserData user)
    {
        if(players.ContainsKey(user.username))
        {
            //销毁玩家
            Player player = players[user.username];
            Destroy(player.gameObject);

            //删除字典的引用
            players.Remove(user.username);
        }
    }
    /// <summary>
    /// 玩家移动
    /// </summary>
    /// <param name="json">玩家移动数据</param>
    void PlayerMove(MoveData data)
    {
        if (players.ContainsKey(data.username))
        {
            //矫正玩家的位置和旋转
            players[data.username].Reset(data.position, data.rotation);

            //指定玩家移动
            players[data.username].Move(data.direct);
        }
    }

    /// <summary>
    /// 老玩家位置信息
    /// </summary>
    /// <param name="user">玩家数据</param>
    void PlayerPos(UserData user)
    {
        //已存在用户，更新位置
        if (players.ContainsKey(user.username))
        {
            players[user.username].transform.position = user.pos;
        }
        else//不存在玩家，创建玩家
        {
            CreatePlayer(user);
        }
    }

    /// <summary>
    /// 玩家开火
    /// </summary>
    /// <param name="data">开火的信息</param>
    void OnPlayerFire(FireData data)
    {
        if (players.ContainsKey(data.username))
        {
            string username = data.username;
            players[username].Fire(data.force);
        }
    }

    /// <summary>
    /// 目标掉血
    /// </summary>
    /// <param name="data">掉血数据</param>
    void OnPlyaerHit(HitDat data)
    {
        if (players.ContainsKey(data.targetUsername))
        {
            //让目标掉血
            players[data.targetUsername].SetHp(data.hp);

            //给发射子弹方加分数
            //xxxxx
        }
    }

    /// <summary>
    /// 创建一个玩家，绑定Player脚本，存储到players字典中
    /// </summary>
    /// <param name="user">玩家信息</param>
    /// <returns></returns>
    Player CreatePlayer(UserData user)
    {
        GameObject prefab = Resources.Load<GameObject>("Tank");
        //创建游戏对象
        GameObject go = Instantiate(prefab);
        //根据index设置玩家的位置
        go.transform.position = bornPoints[user.index].position;

        Player player = go.GetComponent<Player>();
        player.SetUserData(user);
        
        players.Add(user.username, player);
        return player;
    }
}
